package com.xdf.whiteaccount.service.impl;

import com.xdf.whiteaccount.cloudentity.User;
import com.xdf.whiteaccount.cloudservice.QrLogService;
import com.xdf.whiteaccount.cloudservice.UserService;
import com.xdf.whiteaccount.config.datasource.DynamicDataSource;
import com.xdf.whiteaccount.dao.SysRoleGroupMapper;
import com.xdf.whiteaccount.dao.SysUserRoleGroupMapper;
import com.xdf.whiteaccount.entity.SysRoleGroup;
import com.xdf.whiteaccount.entity.SysUser;
import com.xdf.whiteaccount.entity.SysUserRoleGroup;
import com.xdf.whiteaccount.enums.DatasourceKey;
import com.xdf.whiteaccount.exception.UserLoginErrorException;
import com.xdf.whiteaccount.service.LoginService;
import com.xdf.whiteaccount.service.SysUserService;
import com.xdf.whiteaccount.utils.MD5Util;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import java.util.ArrayList;
import java.util.Map;
import java.util.Optional;

/**
 * @program: white-account
 * @description:
 * @author: 张柯
 * @create: 2021-06-11 16:38
 **/
@Service
@Slf4j
public class LoginServiceImpl implements LoginService {
    @Autowired
    private UserService userService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysUserRoleGroupMapper sysUserRoleGroupMapper;
    @Autowired
    private SysRoleGroupMapper sysRoleGroupMapper;
    @Autowired
    private QrLogService qrLogService;

    @Override
    public int insertUser(SysUser sysUser) throws Exception {
        User cloudUser = userService.selectByOpenId(sysUser.getOpenid());
        Assert.notNull(cloudUser, "请关注公众号后再登录！");
        int result = sysUserService.insertSelective(sysUser);
        SysRoleGroup param = SysRoleGroup.builder().build();

        //  如果是本厂用户则自动设置管理员权限
        if (Optional.ofNullable(cloudUser).map(User::getCompany).orElse(false)) {
            param.setRoleGroupAdminSign(true);
        } else {
            param.setIsInitialSelect(true);
        }
        SysRoleGroup record = Optional.ofNullable(sysRoleGroupMapper.selectByParam(param)).orElse(new ArrayList<>()).stream().findFirst().orElse(null);
        if (record != null) {
            result += sysUserRoleGroupMapper.insertSelective(SysUserRoleGroup.builder()
                    .sysUserId(sysUser.getId())
                    .sysRoleGroupId(record.getId())
                    .build());
        }
        return result;
    }

    @Override
    public SysUser selectUser(String userId) throws Exception {
        return sysUserService.selectByLoginName(userId);
    }

    @Override
    public int login(String qrcode) throws Exception {
        Assert.state(StringUtils.isNotEmpty(qrcode), "无UUID，无法登陆！");
        Map<String, Object> result = qrLogService.getLoginMsg(qrcode);
        if (result == null) return 0;
        SysUser user;
        DynamicDataSource.getInstance().setStorageDatasource(String.valueOf(result.get(QrLogService.DATASOURCE_NAME)));
        user = selectUser(String.valueOf(result.get(QrLogService.OPENID)));
        if (user == null) {
            //  创建新用户，默认密码为空字符串
            insertUser(SysUser.builder()
                    .loginName(String.valueOf(result.get(QrLogService.OPENID)))
                    .userName(String.valueOf(result.get(QrLogService.USER_NAME)))
                    .nickName(String.valueOf(result.get(QrLogService.NICK_NAME)))
                    .openid(String.valueOf(result.get(QrLogService.OPENID)))
                    .loginPassword("").build());
            user = selectUser(String.valueOf(result.get(QrLogService.OPENID)));
        }
        Assert.notNull(user, "用户不存在！");
        UsernamePasswordToken token = new UsernamePasswordToken(user.getLoginName(), MD5Util.toMD5(user.getLoginPassword()));
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);
        } catch (IncorrectCredentialsException e) {
            throw new UserLoginErrorException("密码错误！");
        } catch (Exception e) {
            throw new UserLoginErrorException(e.getMessage());
        }
        Session session = subject.getSession();
        session.touch();
        session.setAttribute(DatasourceKey.CURRENT_DATASOURCE_KEY, result.get(QrLogService.DATASOURCE_NAME));
        //  本地真实姓名更改
        //  取自云数据库中user_mill表中的真实姓名
        try {
            sysUserService.updateByPrimaryKeySelectiveWithoutTransactional(
                    SysUser.builder()
                            .id(user.getId())
                            .nickName(String.valueOf(result.get(QrLogService.NICK_NAME)))
                            .userName(String.valueOf(result.get(QrLogService.USER_NAME))).build());
        } catch (Exception e) {
            log.error("登录中修改当前用户失败！首次登录可能切换数据源暂时出错，以后不会出错了！");
            log.error("当前openid:{}", user.getLoginName());
            log.error(e.getMessage());
        }
        return 1;
    }
}